#include <iostream>
#include <assert.h>

using namespace std;

//int main()
//{
//	int a = 0;
//
//	// 引用，b就是a的别名
//	int& b = a;
//
//	cout << &b << endl;
//	cout << &a<< endl;
//
//	b++;
//	a++;
//
//	int& c = a;
//	int& d = c;
//	d++;
//
//	return 0;
//}

// 做参数
//void Swap(int* a, int *b)
//{
//	//...
//}
//
//void Swap(int& a, int &b)
//{
//	int tmp = a;
//	a = b;
//	b = tmp;
//}
//
//int main()
//{
//	int x = 0, y = 1;
//	Swap(&x, &y);
//	Swap(x, y);
//
//	return 0;
//}

//int main()
//{
//	int a = 0;
//
//	// 1、引用必须初始化
//	//int& b;
//	// b = c;
//
//	// 2、引用定义后，不能改变指向
//	int& b = a;
//	int c = 2;
//	b = c;  // 不是改变指向，而是赋值
//
//	// 3、一个变量可以有多个引用，多个别名
//	int& d = b;
//
//	return 0;
//}

// 指针和引用的功能是类似的，有重叠的
// C++的引用，对指针使用比较复杂的场景进行一些替换，让代码更简单易懂，但是不能完全替代指针
// 引用不能完全替代指针原因：引用定义后，不能改变指向
//struct Node
//{
//	struct Node* next;
//	struct Node* prev;
//	int val;
//};
//
////void PushBack(struct Node* phead, int x)
////{
////	// phead = newnode;
////}
//
////void PushBack(struct Node** pphead, int x)
////{
////	// *pphead = newnode;
////}
//
//void PushBack(struct Node*& phead, int x)
//{
//	//phead = newnode;
//}
//
//int main()
//{
//	struct Node* plist = NULL;
//
//	return 0;
//}

//typedef struct Node
//{
//	struct Node* next;
//	struct Node* prev;
//	int val;
//}LNode, *PNode;
//
//void PushBack(PNode& phead, int x)
//{
//	//phead = newnode;
//}
//
////void PushBack(SeqList* ps, int x);
////void PushBack(SeqList& ps, int x);
////{}
//
//int main()
//{
//	PNode plist = NULL;
//
//	return 0;
//}

// 10:40
// 引用 1、做参数（a、输出型参数 b、对象比较大，减少拷贝，提高效率）
// 这些效果，指针也可以，但是引用更方便
//void Swap(int& a, int &b)
//int* preorderTraversal(struct TreeNode* root, int* returnSize)
//int* preorderTraversal(struct TreeNode* root, int& returnSize)

//#include <time.h>
//
//struct A { int a[10000]; };
//void TestFunc1(A a) {}
//void TestFunc2(A& a) {}
//void main()
//{
//	A a;
//	// 以值作为函数参数
//	size_t begin1 = clock();
//	for (size_t i = 0; i < 10000; ++i)
//		TestFunc1(a);
//	size_t end1 = clock();
//
//	// 以引用作为函数参数
//	size_t begin2 = clock();
//	for (size_t i = 0; i < 10000; ++i)
//		TestFunc2(a);
//	size_t end2 = clock();
//
//	// 分别计算两个函数运行结束后的时间
//	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
//	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
//}

////////////////////////////////////////////////////////////////////
// 引用：2、做返回值 (a、修改返回对象 b、减少拷贝提高效率)

//int func()
//{
//	int a = 0;
//	return a;
//}
//
//int main()
//{
//	int ret = func();
//	cout << ret << endl;
//
//	return 0;
//}

// 错误示范
//int& func()
//{
//	int a = 0;
//	return a;
//}
//
//int main()
//{
//	int ret = func();
//	cout << ret << endl;
//
//	return 0;
//}

//int& func()
//{
//	int a = 0;
//	return a;
//}
//
//int& fx()
//{
//	int b = 1;
//	return b;
//}
//
//int main()
//{
//	int& ret = func();
//	cout << ret << endl;
//
//	fx();
//	cout << ret << endl;
//
//	return 0;
//}

//int& func()
//{
//	static int a = 0;
//	return a;
//}
//
//int main()
//{
//	int ret = func();
//	cout << ret << endl;
//
//	return 0;
//}

//struct SeqList
//{
//	int* a;
//	int size;
//	int capacity;
//};
//
//void SLInit(SeqList& sl)
//{
//	sl.a = (int*)malloc(sizeof(int) * 4);
//	// ..
//	sl.size = 0;
//	sl.capacity = 4;
//}
//
//void SLPushBack(SeqList& sl, int x)
//{
//	//...扩容
//	sl.a[sl.size++] = x;
//}
//
//// 修改
//void SLModity(SeqList& sl, int pos, int x)
//{
//	assert(pos >= 0);
//	assert(pos < sl.size);
//
//	sl.a[pos] = x;
//}
//
//int SLGet(SeqList& sl, int pos)
//{
//	assert(pos >= 0);
//	assert(pos < sl.size);
//
//	return sl.a[pos];
//}
//
//int main()
//{
//	SeqList s;
//	SLInit(s);
//	SLPushBack(s, 1);
//	SLPushBack(s, 2);
//	SLPushBack(s, 3);
//	SLPushBack(s, 4);
//
//	for (int i = 0; i < s.size; i++)
//	{
//		cout << SLGet(s, i) << " ";
//	}
//	cout << endl;
//
//	for (int i = 0; i < s.size; i++)
//	{
//		int val = SLGet(s, i);
//		if (val % 2 == 0)
//		{
//			SLModity(s, i, val * 2);
//		}
//	}
//	cout << endl;
//
//	for (int i = 0; i < s.size; i++)
//	{
//		cout << SLGet(s, i) << " ";
//	}
//	cout << endl;
//
//
//	return 0;
//}

// C++
struct SeqList
{
	// 成员变量
	int* a;
	int size;
	int capacity;

	// 成员函数
	void Init()
	{
		a = (int*)malloc(sizeof(int) * 4);
		// ...
		size = 0;
		capacity = 4;
	}

	void PushBack(int x)
	{
		// ... 扩容
		a[size++] = x;
	}

	// 11:57继续
	// 读写返回变量
	int& Get(int pos)
	{
		assert(pos >= 0);
		assert(pos < size);

		return a[pos];
	}

	int& operator[](int pos)
	{
		assert(pos >= 0);
		assert(pos < size);

		return a[pos];
	}
};

//int main()
//{
//	SeqList s;
//	s.Init();
//	s.PushBack(1);
//	s.PushBack(2);
//	s.PushBack(3);
//	s.PushBack(4);
//
//	for (int i = 0; i < s.size; i++)
//	{
//		//cout << s.Get(i)<< " ";
//		cout << s[i] << " ";
//		//cout << s.operator[](i) << " ";
//	}
//	cout << endl;
//
//	for (int i = 0; i < s.size; i++)
//	{
//		/*if (s.Get(i) % 2 == 0)
//		{
//			s.Get(i) *= 2;
//		}*/
//		if (s[i] % 2 == 0)
//		{
//			s[i] *= 2;
//		}
//	}
//	cout << endl;
//
//	for (int i = 0; i < s.size; i++)
//	{
//		cout << s.Get(i) << " ";
//	}
//	cout << endl;
//
//	return 0;
//}

//int main()
//{
//	int a = 10;
//	int& ra = a;  // 语法不开空间，
//	ra = 20;
//
//	int* pa = &a; // 语法上开空间
//	*pa = 20;
//
//	return 0;
//}

// 频繁调用100w次，建立100w个栈帧
// c语言如何解决这个问题的？宏函数
//int Add(int a, int b)
//{
//	return a + b;
//}

// 容易犯错注意点：
// 1、不是函数
// 2、分号
// 3、括号控制优先级
// 核心点：宏是预处理阶段进行替换
//#define ADD(int a, int b) return a+b;
//#define ADD(a, b) a+b;
//#define ADD(a, b) (a+b)
//#define ADD(a, b) ((a)+(b))

// 为什么要加里面的括号？
//int main()
//{
//	if (ADD(1, 2))
//	{}
//
//	ADD(1, 2) * 3;
//
//	int x = 1, y = 2;
//	ADD(x | y, x & y);  // (x|y + x&y)
//
//	return 0;
//}

// 宏的缺点：
// 1、语法复杂，坑很多，不容易控制
// 2、不能调试
// 3、没有类型安全的检查

inline int Add(int a, int b)
{
	return a + b;
}

int main()
{
	int ret1 = Add(1, 2) * 3;

	int x = 1, y = 2;
	int ret2 = Add(x | y, x & y);

	return 0;
}
